import { compare, hash } from "bcryptjs";
import { sign } from "jsonwebtoken";
import { objectType, extendType, stringArg } from "@nexus/schema";
import { APP_SECRET } from "../utils";

export const AuthPayload = objectType({
  name: "AuthPayload",
  definition(t) {
    t.string("token");
    t.field("user", { type: "User" });
  },
});

export const SignupMutation = extendType({
  type: "Mutation",
  definition(t) {
    t.field("signup", {
      type: "AuthPayload",
      args: {
        name: stringArg({ required: true }),
        password: stringArg({ required: true }),
      },
      resolve: async (_root, args, ctx) => {
        console.log("name,password:", args.name, args.password);
        const hashedPassword = await hash(args.password, 10);
        // if has the user
        const user_check = await ctx.db.user.findOne({
          where: { name: args.name },
        });
        console.log("user check:", user_check);

        if (user_check) {
          throw new Error("same user");
        }

        const user = await ctx.db.user.create({
          data: {
            name: args.name,
            password: hashedPassword,
          },
        });
        console.log("create user:", user);

        const result = await ctx.db.authPayload.create({
          data: {
            token: sign({ userId: user.id }, APP_SECRET),
            user: { connect: { id: user.id } },
          },
        });
        console.log("create user result:", result);

        return result;
      },
    });
  },
});

export const SigninMutation = extendType({
  type: "Mutation",
  definition(t) {
    t.field("signin", {
      type: "AuthPayload",
      args: {
        name: stringArg({ required: true }),
        password: stringArg({ required: true }),
      },
      resolve: async (_root, args, ctx) => {
        const user = await ctx.db.user.findOne({
          where: {
            name: args.name,
          },
        });

        if (!user) {
          throw new Error(`No user found for name: ${args.name}`);
        }

        const passwordValid = await compare(args.password, user.password);
        if (!passwordValid) {
          throw new Error("Invalid password");
        }

        const token = sign({ userId: user.id }, APP_SECRET);

        // return {
        //   token: token,
        //   user: user,
        // };

        return ctx.db.authPayload.create({
          data: {
            token,
            user: { connect: { id: user.id } },
          },
        });
      },
    });
  },
});
